﻿using CSharp_Remote_Control.Model;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CSharp_Remote_Control.Utils
{
    internal class TCPClient
    {

        public volatile TcpClient? Client;
        public bool IsRunning;
        Thread MsgThread;

        object lockObject = new object();

        public delegate void OnClientStartDelegate(string serverIp, int port);
        public event OnClientStartDelegate? OnClientStartEvent;

        public delegate void OnClientCloseDelegate();
        public event OnClientCloseDelegate? OnClientCloseEvent;

        public delegate void OnServerMsgDelegate(String? s);
        public event OnServerMsgDelegate? OnServerMsgEvent;

        public delegate void OnServerMsgJsonDelegate(String? s);
        public event OnServerMsgJsonDelegate? OnServerMsgJsonEvent;

        public delegate void OnClientConnectDelegate();
        public event OnClientConnectDelegate? OnClientConnectEvent;

        public TCPClient() { }


        public void Open(string serverIp = "127.0.0.1", int port = 5000)
        {
            try
            {
                IsRunning = true;
                Client = new TcpClient(serverIp, port);
                IPEndPoint? clientIpEndPoint = (IPEndPoint)Client.Client.RemoteEndPoint;
                if (clientIpEndPoint != null)
                {
                    OnClientStartEvent?.Invoke(
                   clientIpEndPoint.Address.ToString()
                   , clientIpEndPoint.Port
                   );
                }

                // 连接成功后存储到全局缓存中
                StaticItem.Clients.Add(this);


                // 监听服务器数据
                MsgThread = new Thread(() =>
               {
                   try
                   {
                       string message = "";
                       string jsonStr = "";
                       while (IsRunning)
                       {

                           // 读取服务器回显
                           byte[] buffer = new byte[1024];
                           int bytesRead = Client.GetStream().Read(buffer, 0, buffer.Length);
                           message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                           OnServerMsgEvent?.Invoke(message);

                           if (message == MsgUtil.getBegin())
                           {
                               message = "";
                               jsonStr = "";
                           }
                           else if (message == MsgUtil.getEnd())
                           {
                               // 获取到完整数据
                               OnServerMsgJsonEvent?.Invoke(jsonStr.Trim('|'));

                               message = "";
                               jsonStr = "";
                           }
                           else
                           {
                               jsonStr += message;
                           }
                       }
                   }
                   catch (Exception ex)
                   {
                       Debug.WriteLine("错误: " + ex.Message);
                   }
                  
               });
                MsgThread.Start();
            }
            catch (Exception ex)
            {
                Debug.WriteLine("错误: " + ex.Message);
            }
        }

        /// <summary>
        /// 发送TransformModel对象
        /// </summary>
        /// <param name="s"></param>
        public void SendMsgObj(TransformModel s)
        {
            this.SendMsg(MsgUtil.TCPMsgWrapTO(s));
        }


        /// <summary>
        /// 发送字符串消息
        /// </summary>
        /// <param name="s"></param>
        public void SendMsg(string s)
        {
            byte[] data = Encoding.UTF8.GetBytes(s);
            if(IsRunning)
            {
                Client?.GetStream().Write(data, 0, data.Length);
            }
        }


        public void Close()
        {
            IsRunning = false;
            MsgThread?.Interrupt();
            Client?.GetStream().Close();
            Client?.Close();
        }

    }
}
